// Copyright [2020] <unknown>
#include <bits/stdc++.h>
using namespace std;
// #define ONLINE_JUDGE
#ifndef ONLINE_JUDGE
#define dbg(x...) { cerr << "\033[32;1m" << #x << " -> "; err(x); }
void err() { cerr << "\033[39;0m" << endl; }
template<typename T, typename... A>
void err(T a, A... x) { cerr << a << ' '; err(x...); }
#else
#define dbg(...)
#endif

#define sz(x) ((int)x.size())

typedef long long LL;

const int N = 2050;

char s[3][N];

inline bool cmp(char a, char b) {
    if (a == '?' || b == '?')
        return true;
    return a == b;
}

bool g[3][3][N];
void maxTry(char a[], int n, char b[], int m, bool res[]) {
    for (int i=0; i<n; ++i) {
        bool suc = true;
        for (int j=0; j<m && i+j<n; ++j) {
            if (!cmp(a[i+j], b[j])) {
                suc = false;
                break;
            }
        }
        if (suc) {
            res[i] = 1;
        }
    }
    res[n] = 1;
}

int main(int argc, char const *argv[]) {
    // code

    int p[] = {0, 1, 2};
    scanf("%s%s%s", s[0], s[1], s[2]);
    int len[] = {strlen(s[0]), strlen(s[1]), strlen(s[2])};

    for (int i=0; i<3; ++i)
        for (int j=0; j<3; ++j) {
            if (i != j)
                maxTry(s[i], len[i], s[j], len[j], g[i][j]);
        }
    // dbg(len[0], len[1], len[2]);
    int ans = 1e9;
    do {
        for (int i=0; i<=len[p[0]]; ++i) {
            if (!g[p[0]][p[1]][i])
                continue;
            int newlen = max(len[0], len[1] + i);
            for (int j=0; j<=newlen; ++j) {
                if (j < len[p[0]] && !g[p[0]][p[2]][j])
                    continue;
                if (j - i >= 0 && j-i < len[p[1]] && !g[p[1]][p[2]][j-i])
                    continue;
                if (i - j >= 0 && i-j < len[p[2]] && !g[p[2]][p[1]][i-j])
                    continue;
                int tans = max(len[p[0]], max(i + len[p[1]], j + len[p[2]]));
                ans = min(ans, tans);
            }
        }
            
    } while (next_permutation(p, p+3));
    cout << ans << endl;
    return 0;
}
